package com.zero.yygh.user.api;

import com.alibaba.fastjson.JSONObject;
import com.zero.yygh.common.exception.CommonException;
import com.zero.yygh.common.helper.JwtHelper;
import com.zero.yygh.common.result.Result;
import com.zero.yygh.common.result.ResultCodeEnum;
import com.zero.yygh.common.utils.HttpClientUtils;
import com.zero.yygh.model.user.UserInfo;
import com.zero.yygh.user.config.ConstantPropertiesUtil;
import com.zero.yygh.user.service.UserInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

/**
 * @author zero
 * @desc 微信API接口
 * @create 2021/4/6
 */
@Api("微信接口")
@Controller
@RequestMapping("/api/ucenter/wx")
@Slf4j
public class WechatApiController {

    @Resource
    private UserInfoService userInfoService;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @ApiOperation("获取微信登录参数")
    @GetMapping("getLoginParam")
    @ResponseBody
    public Result<Map<String, Object>> genQrConnect(HttpSession session) throws UnsupportedEncodingException {
        String redirectUri = URLEncoder.encode(ConstantPropertiesUtil.WECHAT_OPEN_REDIRECT_URL, "UTF-8");
        Map<String, Object> map = new HashMap<>(4);
        map.put("appid", ConstantPropertiesUtil.WECHAT_OPEN_APP_ID);
        map.put("redirectUri", redirectUri);
        map.put("scope", "snsapi_login");
        map.put("state", System.currentTimeMillis() + "");
        return Result.ok(map);
    }

    @ApiOperation("微信登录回调")
    @GetMapping("callback")
    public String callback(String code, String state) throws UnsupportedEncodingException {
        // 获取授权时的票据
        if(StringUtils.isEmpty(code) || StringUtils.isEmpty(state)) {
            log.error("非法回调");
            throw new CommonException(ResultCodeEnum.ILLEGAL_CALLBACK_REQUEST_ERROR);
        }
        //使用 code 和 appid 以及 appscrect 换取 access_token
        String baseAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token" +
                "?appid=%s" +
                "&secret=%s" +
                "&code=%s" +
                "&grant_type=authorization_code";
        String accessTokenUrl = String.format(baseAccessTokenUrl,
                ConstantPropertiesUtil.WECHAT_OPEN_APP_ID,
                ConstantPropertiesUtil.WECHAT_OPEN_APP_SECRET,
                code);

        String result;
        try{
            result = HttpClientUtils.get(accessTokenUrl);
            log.debug("使用code换取的access_token结果 = " + result);
        }catch (Exception e) {
            throw new CommonException(ResultCodeEnum.FETCH_ACCESS_TOKEN_FAILED);
        }
        // json格式化结果
        JSONObject resultJson = JSONObject.parseObject(result);
        if (null != resultJson.getString("errcode")) {
            log.error("获取access_token失败：" + resultJson.getString("errcode") + resultJson.getString("errmsg"));
            throw new CommonException(ResultCodeEnum.FETCH_ACCESS_TOKEN_FAILED);
        }
        String accessToken = resultJson.getString("access_token");
        String openId = resultJson.getString("openid");
        //先根据openid进行数据库查询
        UserInfo userInfo = userInfoService.getByOpenId(openId);
        // 如果没有查到用户信息,那么调用微信个人信息获取的接口
        if(null == userInfo){
            //如果查询到个人信息，那么直接进行登录
            // 使用access_token换取受保护的资源：微信的个人信息
            String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo" +
                    "?access_token=%s" +
                    "&openid=%s";
            String userInfoUrl = String.format(baseUserInfoUrl, accessToken, openId);
            String resultUserInfo;
            try {
                resultUserInfo = HttpClientUtils.get(userInfoUrl);
                log.info("使用access_token获取用户信息的结果 = " + resultUserInfo);
            } catch (Exception e) {
                throw new CommonException(ResultCodeEnum.FETCH_USERINFO_ERROR);
            }
            JSONObject resultUserInfoJson = JSONObject.parseObject(resultUserInfo);
            if(resultUserInfoJson.getString("errcode") != null){
                log.error("获取用户信息失败：" + resultUserInfoJson.getString("errcode") + resultUserInfoJson.getString("errmsg"));
                throw new CommonException(ResultCodeEnum.FETCH_USERINFO_ERROR);
            }
            //解析用户信息
            String nickname = resultUserInfoJson.getString("nickname");
            String headimgurl = resultUserInfoJson.getString("headimgurl");

            userInfo = new UserInfo();
            userInfo.setOpenid(openId);
            userInfo.setNickName(nickname);
            userInfo.setStatus(1);
            userInfoService.save(userInfo);
        }
        String name = userInfo.getName();
        if(StringUtils.isEmpty(name)) {
            name = userInfo.getNickName();
        }
        if(StringUtils.isEmpty(name)) {
            name = userInfo.getPhone();
        }
        String token = JwtHelper.createToken(userInfo.getId(), name);
        return "redirect:" + ConstantPropertiesUtil.YYGH_BASE_URL
                + "/wechat/callback?token=" + token
                + "&openid=" + (StringUtils.isEmpty(userInfo.getPhone()) ? userInfo.getOpenid() : "")
                + "&name=" + URLEncoder.encode(name, "utf-8");

    }
}
